/**
 * @file lv_port_disp_templ.c
 *
 */

 /*Copy this file as "lv_port_disp.c" and set this value to "1" to enable content*/
#if 1

/*********************
 *      INCLUDES
 *********************/
#include "lv_port_disp.h"
#include "lvgl.h"
#include "at32f403a_407_board.h"
#include "dev_st7789v.h"

/*********************
 *      DEFINES
 *********************/
#define SCREEN_BUFFER_SIZE          (MY_DISP_HOR_RES/2 * MY_DISP_VER_RES)
/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
/**********************
 *  STATIC VARIABLES
 **********************/
static lv_disp_drv_t* disp_drv_p = NULL;
static lv_disp_draw_buf_t draw_buf_dsc_1;
static lv_color_t buf_1[SCREEN_BUFFER_SIZE];  
                        
/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
 **********************/

void lv_port_disp_init(void)
{
    /* Example for 1) */
		lv_disp_draw_buf_init(&draw_buf_dsc_1, buf_1, NULL, SCREEN_BUFFER_SIZE);

    static lv_disp_drv_t disp_drv;                         /*Descriptor of a display driver*/
    lv_disp_drv_init(&disp_drv);                    /*Basic initialization*/

    /*Set up the functions to access to your display*/

    /*Set the resolution of the display*/
    disp_drv.hor_res = MY_DISP_HOR_RES;
    disp_drv.ver_res = MY_DISP_VER_RES;

    /*Used to copy the buffer's content to the display*/
    disp_drv.flush_cb = disp_flush;
		//disp_drv.wait_cb = disp_wait_cb;
    /*Set a display buffer*/
    disp_drv.draw_buf = &draw_buf_dsc_1;

    /*Finally register the driver*/
    lv_disp_drv_register(&disp_drv);
}

/**********************
 *   STATIC FUNCTIONS
 **********************/

/*Flush the content of the internal buffer the specific area on the display
 *You can use DMA or any hardware acceleration to do this operation in the background but
 *'lv_disp_flush_ready()' has to be called when finished.*/
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
	 disp_drv_p = disp_drv;
	/*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/

	 const lv_coord_t w = (area->x2 - area->x1 + 1);
	 const lv_coord_t h = (area->y2 - area->y1 + 1);
	 const uint32_t len = w * h;

	 st7789_setwindow(area->x1, area->y1, area->x2, area->y2);

	 st7789_send_pixels((uint16_t*)color_p, len);

}

void SPI1_DMA_CB(void)
{
	/*Inform the graphics library that you are ready with the flushing*/
	lv_disp_flush_ready(disp_drv_p);
}


#endif
